#pragma once

//////////////////////////////////////////////////////////////////////////
//
// Useful mathematical functions
//
//////////////////////////////////////////////////////////////////////////

#include <DirectXMath.h>

template<typename T>
T 
computeMax(const T& a, const T& b) { 
    return a > b ? a : b; 
}

template<typename T>
T 
computeMin(const T& a, const T& b) { 
    return a < b ? a : b; 
}

template<typename T>
T 
clamp(const T& x, const T& low, const T& high) {
    return x < low ? low : (x > high ? high : x); 
}

// Returns random float in [0, 1).
float 
randomFloat();

// Returns random float in [min, max).
float 
randomFloat(const float min, const float max);

void 
inverseTranspose(DirectX::CXMMATRIX m, DirectX::XMMATRIX& out);

// Based on x and z coordinates, it returns
// y coordinates which represents height
float 
height(const float x, const float z);

// Euler angle from positive x axis
// to the segment that goes from (0, 0) --> (x, y)
float 
eulerAngle(const float x, const float y);

// Returns true if num1 and num2 are equals.
// This function takes into account an epsilon
// for the comparison.
bool 
areEquals(const float num1, const float num2, const float epsilon = 1.0E-5);

// Get the angle in radians that we need to rotate
// from src to dest 
float 
rotationAngle(DirectX::FXMVECTOR& src, DirectX::FXMVECTOR& dest);

// Rotates vec around Y axis by angle
void 
rotateAroundYAxis(DirectX::XMVECTOR& v, const float angle);

// Set XMVector3A values
void 
set(const float x, const float y, const float z, DirectX::XMFLOAT3A& vec);

// Set XMVector3 values
void 
set(const float x, const float y, const float z, DirectX::XMFLOAT3& vec);

// Set length of a XMVECTOR
void 
setLength(DirectX::XMVECTOR& v, const float len);

// Returns true if vector is zero
bool 
isZero(DirectX::FXMVECTOR& vec);